package com.demo.java.spring;

import org.springframework.expression.*;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.Assert;

import java.util.HashMap;
import java.util.Map;

public class SpringElTest {

    public static void main(String[] args) {
        // 使用spring el表达式解析模板字符串
        ExpressionParser parser = new SpelExpressionParser();

        Map<String, Object> model = new HashMap<>();
        model.put("topic", "test");
        model.put("time", System.currentTimeMillis());

        StandardEvaluationContext context = new StandardEvaluationContext(model);
        context.addPropertyAccessor(new MapPropertyAccessor());

        Expression expression = parser.parseExpression("#{topic}-#{time}", ParserContext.TEMPLATE_EXPRESSION);
        String str = expression.getValue(context, String.class);
        System.out.println(str);
    }

    static class MapPropertyAccessor implements PropertyAccessor {

        public Class<?>[] getSpecificTargetClasses() {
            return new Class[]{Map.class};
        }

        public boolean canRead(EvaluationContext context, Object target, String key) throws AccessException {
            return target instanceof Map && ((Map) target).containsKey(key);
        }

        public TypedValue read(EvaluationContext context, Object target, String key) throws AccessException {
            Assert.state(target instanceof Map, "参数不是Map类型");
            Map<?, ?> map = (Map<?, ?>) target;
            if (!map.containsKey(key)) {
                throw new AccessException("Map中未包含该key: " + key);
            }
            Object value = map.get(key);
            return new TypedValue(value);
        }

        public boolean canWrite(EvaluationContext evaluationContext, Object o, String s) throws AccessException {
            return false;
        }

        public void write(EvaluationContext evaluationContext, Object o, String s, Object o1) throws AccessException {

        }
    }
}
